package com.liuh.okhttp.builder;

import java.io.File;
import java.io.UnsupportedEncodingException;
import java.net.FileNameMap;
import java.net.URLConnection;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import okhttp3.FormBody;
import okhttp3.Headers;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.Request;
import okhttp3.RequestBody;

/**
 * @note 表单及文件postBuilder构造
 * @author liuh
 * */
public class PostFormBuilder extends OkHttpRequestBuilder<PostFormBuilder> {

	private List<FileInput> files = new ArrayList<>();

	public static class FileInput {
		public String key;
		public String filename;
		public File file;

		public FileInput(String name, String filename, File file) {
			this.key = name;
			this.filename = filename;
			this.file = file;
		}

		@Override
		public String toString() {
			return "FileInput{" + "key='" + key + '\'' + ", filename='"
					+ filename + '\'' + ", file=" + file + '}';
		}
	}

	public PostFormBuilder files(String key, Map<String, File> files) {
		for (String filename : files.keySet()) {
			this.files.add(new FileInput(key, filename, (File) files
					.get(filename)));
		}
		return this;
	}

	public PostFormBuilder addFile(String name, String filename, File file) {
		this.files.add(new FileInput(name, filename, file));
		return this;
	}

	public PostFormBuilder params(Map<String, String> params) {
		this.params = params;
		return this;
	}

	public PostFormBuilder addParams(String key, String val) {
		if (this.params == null) {
			params = new LinkedHashMap<>();
		}
		params.put(key, val);
		return this;
	}

	/**
	 * @note MultipartBodyBuilder 添加参数
	 * @author liuh
	 * */
	private void addParams(MultipartBody.Builder builder) {
		if ((this.params != null) && (!this.params.isEmpty())) {
			for (String key : this.params.keySet()) {
				builder.addPart(
						Headers.of(new String[] { "Content-Disposition",
								"form-data; name=\"" + key + "\"" }),
						RequestBody.create(null, (String) this.params.get(key)));
			}
		}
	}

	/**
	 * @note FormBodyBuilder 添加参数
	 * @author liuh
	 * */
	private void addParams(FormBody.Builder builder) {
		if (this.params != null) {
			for (String key : this.params.keySet()) {
				builder.add(key, (String) this.params.get(key));
			}
		}
	}

	/**
	 * @note 获取文件类型Mime Type
	 * @author liuh
	 * */
	private String guessMimeType(String fileName) {
		FileNameMap fileNameMap = URLConnection.getFileNameMap();
		String contentTypeFor = null;
		try {
			contentTypeFor = fileNameMap.getContentTypeFor(URLEncoder.encode(
					fileName, "UTF-8"));
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		if (contentTypeFor == null) {
			contentTypeFor = "application/octet-stream";
		}
		return contentTypeFor;
	}

	/**
	 * @note 构造请求参数
	 * @author liuh
	 * */
	@Override
	public Request builderRequest() {
		// TODO Auto-generated method stub
		Request.Builder mBuilder = builderBaseRequest();
		if ((this.files == null) || (this.files.isEmpty())) {
			FormBody.Builder form_builder = new FormBody.Builder();
			addParams(form_builder);
			//
			mBuilder.post(form_builder.build());
		} else {
			MultipartBody.Builder multipart_builder = new MultipartBody.Builder()
					.setType(MultipartBody.FORM);
			addParams(multipart_builder);
			// MultipartBodyBuilder添加文件参数
			for (int i = 0; i < this.files.size(); i++) {
				PostFormBuilder.FileInput fileInput = (PostFormBuilder.FileInput) this.files
						.get(i);
				RequestBody fileBody = RequestBody.create(
						MediaType.parse(guessMimeType(fileInput.filename)),
						fileInput.file);
				multipart_builder.addFormDataPart(fileInput.key,
						fileInput.filename, fileBody);
			}
			//
			mBuilder.post(multipart_builder.build());
		}
		return mBuilder.build();
	}
}
